package net.butfly.bus.context;

import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;

public abstract class Context implements Map<String, Serializable> {

	public static Context CURRENT;
	private static String RANDOM_SEED;
	static {
		CURRENT = new ThreadLocalContext();
		RANDOM_SEED = "";
		for (int i = 0; i < 10; i++) {
			RANDOM_SEED = RANDOM_SEED + i;
		}
	}

	/****************************************************/

	public enum Mode {
		ReplacingByCleaning, MergingWithNew, MergingOnlyAbsent;
	}

	public abstract Map<String, Serializable> toMap();

	public static void merge(Map<String, Serializable> dst, Map<String, Serializable> src) {
		merge(dst, src, Mode.MergingWithNew);
	}

	public static void merge(Map<String, Serializable> dst, Map<String, Serializable> src, Mode mode) {
		if (src == null || dst == null)
			return;
		switch (mode) {
		case ReplacingByCleaning:
			dst.clear();
			dst.putAll(src);
			return;
		case MergingWithNew:
			dst.putAll(src);
			return;
		case MergingOnlyAbsent:
			for (Entry<String, Serializable> e : src.entrySet())
				dst.putIfAbsent(e.getKey(), e.getValue());
			return;
		}
	}

	/****************************************************/
	public enum Key {
		FlowNo, TXCode, SourceAppID, SourceHost, UserID;
	}

	public static FlowNo getFlowNo() {
		return (FlowNo) CURRENT.get(Key.FlowNo.name());
	}

	public static String getSourceAppID() {
		return (String) CURRENT.get(Key.SourceAppID.name());
	}

	public static String getSourceHost() {
		return (String) CURRENT.get(Key.SourceHost.name());
	}

	public static String getTXCode() {
		return (String) CURRENT.get(Key.TXCode.name());
	}

	public static String getUserId() {
		return (String) CURRENT.get(Key.UserID.name());
	}

	public static void setFlowNo(FlowNo flowNo) {
		CURRENT.put(Key.FlowNo.name(), flowNo);
	}

	public static void setChannel(String sourceAppID) {
		CURRENT.put(Key.SourceAppID.name(), sourceAppID);
	}

	public static void setSourceHost(String sourceHost) {
		CURRENT.put(Key.SourceHost.name(), sourceHost);
	}

	public static void setTxCode(String txCode) {
		CURRENT.put(Key.TXCode.name(), txCode);
	}

	public static void setUserId(String userId) {
		CURRENT.put(Key.UserID.name(), userId);
	}

	/****************************************************/
	public static FlowNo flowNo(String tx, String version) {
		return FlowNo
				.parse(new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) + getRandomId(7) + "@" + tx + null == version ? ""
						: "[" + version + "]");
	}

	public static FlowNo flowNo() {
		// TODO Auto-generated method stub
		return null;
	}

	private static synchronized String getRandomId(int length) {
		String rst = "";
		for (int i = 0; i < length; i++) {
			int mathInt;
			mathInt = (int) (Math.random() * RANDOM_SEED.length());
			rst = rst + RANDOM_SEED.charAt(mathInt);
		}
		return rst;
	}
}
